package com.lktx.bbfactory.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lktx.bbfactory.common.CommonPage;
import com.lktx.bbfactory.common.exception.BizAsserts;
import com.lktx.bbfactory.entiy.Product;
import com.lktx.bbfactory.entiy.Project;
import com.lktx.bbfactory.entiy.VO.projectListVo;
import com.lktx.bbfactory.mapper.productMapper;
import com.lktx.bbfactory.mapper.projectMapper;
import com.lktx.bbfactory.service.projectService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Service
public class projectServiceImpl extends ServiceImpl<projectMapper, Project> implements projectService {

    @Resource
    private productMapper productMapper;

    @Resource
    private projectMapper projectMapper;

    /**
     * 分页查询项目
     */
    @Override
    public CommonPage<projectListVo> listPage(String code, String name, String client, String status,String clientUsername,
                                        Integer pageNum, Integer pageSize) {
        Page<projectListVo> pageParam = new Page<>(pageNum, pageSize);
        IPage<projectListVo> resultPage = projectMapper.listPageWithProgress(pageParam, code, name, client, status,clientUsername);
        return CommonPage.restPage(resultPage);
    }


    /**
     * 添加项目
     */
    @Override
    public void addProject(Project project) {
        // 校验项目代号唯一
        boolean existsCode = this.lambdaQuery()
                .eq(Project::getCode, project.getCode())
                .exists();
        BizAsserts.isTrue(!existsCode, "项目代号已存在");
        // 校验项目名称唯一
        boolean existsName = this.lambdaQuery()
                .eq(Project::getName, project.getName())
                .exists();
        BizAsserts.isTrue(!existsName, "项目名称已存在");
        this.save(project);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProject(Project project) {
        // 1. 必须有用户ID
        BizAsserts.notNull(project.getId(), "项目ID不能为空");
        // 2. 校验项目代号唯一性（排除自己）
        long countCode= this.count(new LambdaQueryWrapper<Project>()
                .eq(Project::getCode, project.getCode())
                .ne(Project::getId, project.getId()));
        if (countCode > 0) {
            BizAsserts.fail("项目代号已存在");
        }
        // 3. 校验名称唯一性（排除自己）
        long countName = this.count(new LambdaQueryWrapper<Project>()
                .eq(Project::getName, project.getName())
                .ne(Project::getId, project.getId()));
        if (countName > 0) {
            BizAsserts.fail("项目名称已存在");
        }
        // 4. 更新
        this.updateById(project);
    }

    @Override
    public void deleteProject(Long id) {
        int count = Math.toIntExact(productMapper.selectCount(new QueryWrapper<Product>().eq("project_id", id)));
        if (count > 0) {
            // 有关联产品，不能删除，抛业务异常
            BizAsserts.fail("删除失败：存在关联的产品，不能删除该项目");
        }
        this.removeById(id);
    }

    @Override
    public Long proProgress(Long id) {
        //计算amount
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", id);
        queryWrapper.select("sum(amount) as total");
        List<Map<String, Object>> maps = productMapper.selectMaps(queryWrapper);
        Long amount = (Long) maps.get(0).get("total");
        //计算finishAmount
        QueryWrapper<Product> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("project_id", id);
        queryWrapper1.select("sum(finish_amount) as total");
        Long finishAmount = (Long) maps.get(0).get("total");
        return finishAmount/amount;
    }

    @Override
    public Long getIdByName(String name) {
        Project project = this.lambdaQuery()
                .eq(Project::getName, name)
                .one();
        return project != null ? project.getId() : null;
    }
}



